package com.common.utils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.common.core.domain.entity.SysUser;
import lombok.extern.slf4j.Slf4j;

import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Slf4j
public class QueryWrapperUtils {
    private final static String sql = " between {0} and {1} ";

    private final static String lesql = " <= {0} ";

    private final static String gesql = " >= {0} ";

    private final static String eqsql = " = {0} ";

    private final static String insql = " in ";

    public static LambdaQueryWrapper applyChainWrapper(LambdaQueryWrapper wrapper, String start, String end, String dateFormat, String column) {

        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if(StringUtils.isEmpty(dateFormat)){
            return wrapper;
        }
        if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
            try {
                Object startDate = null, endDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式
                        Year startYear = Year.parse(start.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        Year endYear = Year.parse(end.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));

                        startDate = startYear.atMonth(1).atDay(1);
                        endDate = endYear.atMonth(12).atEndOfMonth();
                        startDate = DateUtils.parseDate(startDate);
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式
                        YearMonth startYearMonth = YearMonth.parse(start, DateTimeFormatter.ofPattern("yyyy-MM"));
                        YearMonth endYearMonth = YearMonth.parse(end, DateTimeFormatter.ofPattern("yyyy-MM"));

                        startDate = startYearMonth.atDay(1);
                        endDate = endYearMonth.atEndOfMonth();
                        startDate = DateUtils.parseDate(startDate);
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        startDate = DateUtils.parseDate(start);
                        endDate = DateUtils.parseDate(end);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
                    if (((Comparable) startDate).compareTo(endDate) > 0) {
                        throw new RuntimeException("开始日期应在结束日期之后");
                    } else {
                        wrapper.apply(column + sql, startDate, endDate);
                    }
                } else {
                    throw new RuntimeException("日期转换出现空值");
                }
            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        } else if (StringUtils.isNotEmpty(start)&&StringUtils.isEmpty(end)) {
            try {
                Object startDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式
                        Year startYear = Year.parse(start.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        startDate = startYear.atMonth(1).atDay(1);
                        startDate = DateUtils.parseDate(startDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式
                        YearMonth startYearMonth = YearMonth.parse(start, DateTimeFormatter.ofPattern("yyyy-MM"));
                        startDate = startYearMonth.atDay(1);
                        startDate = DateUtils.parseDate(startDate);

                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        startDate = DateUtils.parseDate(start);

                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                wrapper.apply(column + gesql, startDate);
            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        } else if (StringUtils.isNotEmpty(end)&&StringUtils.isEmpty(start)) {
            try {
                Object endDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式

                        Year endYear = Year.parse(end.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        endDate = endYear.atMonth(12).atEndOfMonth();
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式
                        YearMonth endYearMonth = YearMonth.parse(end, DateTimeFormatter.ofPattern("yyyy-MM"));
                        endDate = endYearMonth.atEndOfMonth();
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        endDate = DateUtils.parseDate(end);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                wrapper.apply(column + lesql, endDate);
            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        }
        return wrapper;
    }

    public static QueryWrapper applyChainWrapper(QueryWrapper wrapper, String start, String end, String dateFormat, String column) {

        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if(StringUtils.isEmpty(dateFormat)){
            return wrapper;
        }
        if (StringUtils.isNotEmpty(start) && StringUtils.isNotEmpty(end)) {
            try {
                Object startDate = null, endDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式
                        Year startYear = Year.parse(start.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        Year endYear = Year.parse(end.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));

                        startDate = startYear.atMonth(1).atDay(1);
                        endDate = endYear.atMonth(12).atEndOfMonth();
                        startDate = DateUtils.parseDate(startDate);
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式
                        YearMonth startYearMonth = YearMonth.parse(start, DateTimeFormatter.ofPattern("yyyy-MM"));
                        YearMonth endYearMonth = YearMonth.parse(end, DateTimeFormatter.ofPattern("yyyy-MM"));

                        startDate = startYearMonth.atDay(1);
                        endDate = endYearMonth.atEndOfMonth();
                        startDate = DateUtils.parseDate(startDate);
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        startDate = DateUtils.parseDate(start);
                        endDate = DateUtils.parseDate(end);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
                    if (((Comparable) startDate).compareTo(endDate) > 0) {
                        throw new RuntimeException("开始日期应在结束日期之后");
                    } else {
                        wrapper.between(column, startDate, endDate);
                    }
                } else {
                    throw new RuntimeException("日期转换出现空值");
                }
            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        }else if(StringUtils.isNotEmpty(start)&&StringUtils.isEmpty(end)){
            try {
                Object startDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式
                        Year startYear = Year.parse(start.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        startDate = startYear.atMonth(1).atDay(1);
                        startDate = DateUtils.parseDate(startDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式
                        YearMonth startYearMonth = YearMonth.parse(start, DateTimeFormatter.ofPattern("yyyy-MM"));
                        startDate = startYearMonth.atDay(1);
                        startDate = DateUtils.parseDate(startDate);
                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        startDate = DateUtils.parseDate(start);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                wrapper.ge(column, startDate);

            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        }else if(StringUtils.isNotEmpty(end)&&StringUtils.isEmpty(start)){
            try {
                Object endDate = null;
                switch (dateFormat) {
                    case "yyyy":
                        // 处理年份格式

                        Year endYear = Year.parse(end.substring(0,4), DateTimeFormatter.ofPattern("yyyy"));
                        endDate = endYear.atMonth(12).atEndOfMonth();
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM":
                        // 处理年月格式

                        YearMonth endYearMonth = YearMonth.parse(end, DateTimeFormatter.ofPattern("yyyy-MM"));
                        endDate = endYearMonth.atEndOfMonth();
                        endDate = DateUtils.parseDate(endDate);
                        break;
                    case "yyyy-MM-dd":
                        // 处理具体日期格式
                        endDate = DateUtils.parseDate(end);
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported date format: " + dateFormat);
                }
                wrapper.le(column, endDate);
            } catch (DateTimeParseException e) {
                throw new IllegalArgumentException("Invalid date format or value provided.", e);
            }
        }
        return wrapper;
    }

    public static LambdaQueryWrapper applyChainWrapper(LambdaQueryWrapper wrapper, String dateStr, String column) {

        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if (StringUtils.isNotEmpty(dateStr)) {
            if (dateStr.startsWith("-")) {
                //查小于该年的
                wrapper.apply("YEAR(" + column + ")" + lesql, dateStr.replace("-", ""));
            } else if (dateStr.endsWith("-")) {
                //查大于该年的
                wrapper.apply("YEAR(" + column + ")" + gesql, dateStr.replace("-", ""));
            } else if (!dateStr.contains("-")) {
                //查等于该年的
                wrapper.apply("YEAR(" + column + ")" + eqsql, dateStr);
            } else {
                List<String> dates = Arrays.asList(dateStr.split("-"));
                if (Integer.parseInt(dates.get(0)) > Integer.parseInt(dates.get(1))) {
                    wrapper.apply("YEAR(" + column + ")" + sql, dates.get(1), dates.get(0));
                } else {
                    wrapper.apply("YEAR(" + column + ")" + sql, dates.get(0), dates.get(1));
                }
            }
        }
        return wrapper;
    }


    public static LambdaQueryWrapper dealInWrapper(LambdaQueryWrapper wrapper, String dateStr, String column) {
        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if (StringUtils.isNotEmpty(dateStr)) {
            List<String> inStr = Arrays.asList(dateStr.split(","));
            if (inStr.size() > 1) {
                String inSql = String.format("('%s')", String.join("','", inStr));
                wrapper.apply(column + insql + inSql);
            } else {
                wrapper.apply(column + eqsql, dateStr);
            }
        }
        return wrapper;
    }

    public static QueryWrapper applyChainWrapper(QueryWrapper wrapper, String dateStr, String column) {

        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if (StringUtils.isNotEmpty(dateStr)) {
            if (dateStr.startsWith("-")) {
                //查小于该年的
                wrapper.apply("YEAR(" + column + ")" + lesql, dateStr.replace("-", ""));
            } else if (dateStr.endsWith("-")) {
                //查大于该年的
                wrapper.apply("YEAR(" + column + ")" + gesql, dateStr.replace("-", ""));
            } else if (!dateStr.contains("-")) {
                //查等于该年的
                wrapper.apply("YEAR(" + column + ")" + eqsql, dateStr);
            } else {
                List<String> dates = Arrays.asList(dateStr.split("-"));
                if (Integer.parseInt(dates.get(0)) > Integer.parseInt(dates.get(1))) {
                    wrapper.apply("YEAR(" + column + ")" + sql, dates.get(1), dates.get(0));
                } else {
                    wrapper.apply("YEAR(" + column + ")" + sql, dates.get(0), dates.get(1));
                }
            }
        }
        return wrapper;
    }

    public static QueryWrapper dealInWrapper(QueryWrapper wrapper, String dateStr, String column) {
        if (Objects.isNull(wrapper)) {
            log.error("query wrapper is null!");
            throw new RuntimeException("检索不能为空");
        }
        if (StringUtils.isNotEmpty(dateStr)) {
            List<String> inStr = Arrays.asList(dateStr.split(","));
            if (inStr.size() > 1) {
                wrapper.in(column, inStr);
            } else {
                wrapper.eq(column, dateStr);
            }
        }
        return wrapper;
    }

    public static LambdaQueryWrapper getParams_achievement(LambdaQueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)) {
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1) {
                    String inSql = String.format("('%s')", String.join("','", split));
                    qw.apply(" unit_id in " + inSql);
                } else {
                    qw.apply(" unit_id = {0}", units);
                }
            }
            //科研人员  查看自己是否在为负责人
        } else if (("biz_kyry").equals(currentRoleKey)) {
            qw.apply(" FIND_IN_SET({0}, authorpids) ", user.getUserRealId());
        }
        return qw;
    }

    public static LambdaQueryWrapper getParams_achievement_field(LambdaQueryWrapper qw, SysUser user,String field) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)) {
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1) {
                    String inSql = String.format("('%s')", String.join("','", split));
                    qw.apply(" unit_id in " + inSql);
                } else {
                    qw.apply(" unit_id = {0}", units);
                }
            }
            //科研人员  查看自己是否在为负责人
        } else if (("biz_kyry").equals(currentRoleKey)) {
            qw.apply(" FIND_IN_SET({0}, "+field+") ", user.getUserRealId());
        }
        return qw;
    }

    public static LambdaQueryWrapper getParams_Nokyry(LambdaQueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)) {
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1) {
                    String inSql = String.format("('%s')", String.join("','", split));
                    qw.apply(" unit_id in " + inSql);
                } else {
                    qw.apply(" unit_id = {0}", units);
                }
            }
        }
        return qw;
    }

    /**
     * 科研秘书查看自己所管理单位数据，附带字段别名
     * @param qw
     * @param user
     * @return
     */
    public static LambdaQueryWrapper getParams_NokyryWithAlias(LambdaQueryWrapper qw, SysUser user,String tableAlias) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)) {
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1) {
                    String inSql = String.format("('%s')", String.join("','", split));
                    qw.apply(" "+tableAlias+".unit_id in " + inSql);
                } else {
                    qw.apply(" "+tableAlias+".unit_id = {0}", units);
                }
            }
        }else if (("biz_kyry").equals(currentRoleKey)) {
            qw.apply(" FIND_IN_SET({0}, authorpids) ", user.getUserRealId());
        }
        return qw;
    }

    public static QueryWrapper getParams_achievement(QueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)) {
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1) {
                    qw.in("unit_id", split);
                } else {
                    qw.eq("unit_id", units);
                }
            }
            //科研人员  查看自己是否在为负责人
        } else if (("biz_kyry").equals(currentRoleKey)) {
            qw.like("authorpids", user.getUserRealId());
        }
        return qw;
    }


    /**
     * 获取权限的默认查询参数-项目模块
     * @return
     */
    public   static QueryWrapper  getParams_project(QueryWrapper qw,SysUser user,String type) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            String[] split = units.split(",");
            if(type.equals("select")){
                qw.in(StringUtils.isNotEmpty(units),"UNIT_ID", Arrays.asList(split));
            }else{
                qw.in(StringUtils.isNotEmpty(units),"zb.UNIT_ID", Arrays.asList(split));
            }

            //科研人员  查看自己是否在AUTHORPIDS里；没有登录信息时默认为科研人员
        } else if (("biz_kyry").equals(currentRoleKey) || StringUtils.isNotBlank(currentRoleKey)) {
            qw.apply("FIND_IN_SET({0}, AUTHORPIDS)", user.getUserRealId());
        }
        return qw;
    }

    /**
     * 获取权限的默认查询参数-出账合同
     * @return
     */
    public  static LambdaQueryWrapper  getParams_contract(LambdaQueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研管理员
        if (("biz_kycgly").equals(currentRoleKey)) {
            //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        } else if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)){
                List<String> split = Arrays.asList(units.split(","));
                if (split.size() > 1){
                    String inSql = String.format("('%s')", String.join("','", split));
                    qw.apply("UNIT_ID in " + inSql);
                }else{
                    qw.apply("UNIT_ID = {0}", units);
                }
            }
            //科研人员  查看自己是否在为负责人
        } else if (("biz_kyry").equals(currentRoleKey)) {
            qw.apply("CHARGER_CODE = {0}",user.getUserRealId());
        }
        return qw;
    }

    /**
     * 获取权限的默认查询参数-项目业务用：变更、中检、结项
     * 科研人员：当前项目；秘书：所属单位是自己管理单位的项目的所有变更；管理员：系统当前分类项目下的所有变更
     * @return
     */
    public static QueryWrapper getParamsProBusiness(QueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        if (("biz_kyms").equals(currentRoleKey)) {
            String units = user.getUnitAdminScopeReal();
            if (StringUtils.isNotEmpty(units)){
                String[] split = units.split(",");
                qw.in(StringUtils.isNotEmpty(units),"pb.UNIT_ID", Arrays.asList(split));
            }
        }
        return qw;
    }

    /**
     * 项目变更检索时处理变更类型
     * @param qw
     * @param changeType
     * @return
     */
    public static QueryWrapper handleChangeType(QueryWrapper qw,String changeType) {
        if(StringUtils.isNotBlank(changeType)){
            String[] changeTypeArray = changeType.split(",");
            String condition = "";
            for(String changeTypeNow:changeTypeArray){
                condition = StringUtils.isNotBlank(condition)?condition+ " or FIND_IN_SET('"+changeTypeNow+"',ALTER_TYPE)":" FIND_IN_SET('"+changeTypeNow+"',ALTER_TYPE)";
            }

            if(StringUtils.isNotBlank(condition)){
                qw.apply("("+condition+")");
            }
        }
        return qw;
    }

    /**
     * 获取权限的默认查询参数-项目业务用：伦理审查,科研服务
     * 科研人员：自己是申请人的；管理员：所有
     * @return
     */
    public static QueryWrapper getParamsEthicalBusiness(QueryWrapper qw, SysUser user,String businessType) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        //科研秘书 查看自己所管理的单位里,是否包含项目所属单位id
        if (("biz_kyry").equals(currentRoleKey) || !StringUtils.isNotBlank(currentRoleKey)) {
            if(businessType.equals("ethical")){
                qw.eq("CHARGER_CODE", user.getUserRealId());
            }else{
                qw.eq("APPLYER_CODE", user.getUserRealId());
            }
        }
        return qw;
    }

    /**
     * 科研诚信 -只有自己和管理员能看到
     * @param qw
     * @param user
     * @return
     */
    public static LambdaQueryWrapper getParams_kycx(LambdaQueryWrapper qw, SysUser user) {
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
       //科研人员  查看自己是为创建人的记录
        if (("biz_kyry").equals(currentRoleKey)) {
            qw.apply(" kycx.CREATEUSERID = {0} ", user.getUserRealId());
        }
        return qw;
    }
}
